Completed
Push — master ( 03001f...fdb517 )
by Elbert
01:08
created

require.args.forEach   D

Complexity

Conditions 10
Paths 10

Size

Total Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 10
c 1
b 0
f 0
nc 10
nop 1
dl 0
loc 31
rs 4.8196

How to fix   Complexity   

Complexity

Complex classes like require.args.forEach often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
/**
2
 * PhantomJS driver
3
 */
4
5
/** global: phantom */
6
/** global: wappalyzer */
7
8
(function() {
9
	var
10
		url,
11
		originalUrl,
12
		scriptDir,
13
		scriptPath      = require('fs').absolute(require('system').args[0]),
14
		resourceTimeout = 9000,
15
		args            = [],    // TODO: Not used, maybe should be `arg`
16
		debug           = false, // Output debug messages
17
		quiet           = false; // Don't output errors
18
19
	try {
20
		// Working directory
21
		scriptDir = scriptPath.split('/'); scriptDir.pop(); scriptDir = scriptDir.join('/');
22
23
		require('fs').changeWorkingDirectory(scriptDir);
24
25
		require('system').args.forEach(function(arg) {
26
			var
27
				value,
28
				arr = /^(--[^=]+)=(.+)$/.exec(arg);
29
30
			if ( arr && arr.length === 3 ) {
31
				arg   = arr[1];
32
				value = arr[2];
33
			}
34
35
			switch ( arg ) {
36
				case '-v':
37
				case '--verbose':
38
					debug = true;
39
40
					break;
41
				case '-q':
42
				case '--quiet':
43
					quiet = true;
44
45
					break;
46
				case '--resource-timeout':
47
					if ( value ) {
48
						resourceTimeout = value;
49
					}
50
51
					break;
52
				default:
53
					url = originalUrl = arg;
54
			}
55
		});
56
57
		if ( !url ) {
58
			throw new Error('Usage: phantomjs ' + require('system').args[0] + ' <url>');
59
		}
60
61
		if ( !phantom.injectJs('wappalyzer.js') ) {
62
			throw new Error('Unable to open file js/wappalyzer.js');
63
		}
64
65
		wappalyzer.driver = {
66
			timeout: 1000,
67
68
			/**
69
			 * Log messages to console
70
			 */
71
			log: function(args) {
72
				if ( args.type === 'error' ) {
73
					if ( !quiet ) {
74
						require('system').stderr.write(args.message + "\n");
75
					}
76
				} else if ( debug || args.type !== 'debug' ) {
77
					require('system').stdout.write(args.message + "\n");
78
				}
79
			},
80
81
			/**
82
			 * Display apps
83
			 */
84
			displayApps: function() {
85
				var
86
					app, cats,
87
					apps  = [];
88
89
				wappalyzer.log('driver.displayApps');
90
91
				for ( app in wappalyzer.detected[url] ) {
92
					cats = [];
93
94
					wappalyzer.apps[app].cats.forEach(function(cat) {
95
						cats.push(wappalyzer.categories[cat].name);
96
					});
97
98
					apps.push({
99
						name: app,
100
						confidence: wappalyzer.detected[url][app].confidenceTotal.toString(),
101
						version:    wappalyzer.detected[url][app].version,
102
						icon:       wappalyzer.apps[app].icon || 'default.svg',
103
						website:    wappalyzer.apps[app].website,
104
						categories: cats
105
					});
106
				}
107
108
				wappalyzer.driver.sendResponse(apps);
109
			},
110
111
			/**
112
			 * Send response
113
			 */
114
			sendResponse: function(apps) {
115
				apps = apps || [];
116
117
				require('system').stdout.write(JSON.stringify({ url: url, originalUrl: originalUrl, applications: apps }) + "\n");
118
			},
119
120
			/**
121
			 * Initialize
122
			 */
123
			init: function() {
124
				var
125
					page, hostname,
126
					headers = {},
127
					a       = document.createElement('a'),
128
					json    = JSON.parse(require('fs').read('apps.json'));
129
130
				wappalyzer.log('driver.init');
131
132
				a.href = url.replace(/#.*$/, '');
133
134
				hostname = a.hostname;
135
136
				wappalyzer.apps       = json.apps;
137
				wappalyzer.categories = json.categories;
138
139
				page = require('webpage').create();
140
141
				page.settings.loadImages      = false;
142
				page.settings.userAgent       = 'Mozilla/5.0 (compatible; Wappalyzer; +https://github.com/AliasIO/Wappalyzer)';
143
				page.settings.resourceTimeout = resourceTimeout;
144
145
				page.onError = function(message) {
146
					wappalyzer.log(message, 'error');
147
				};
148
149
				page.onResourceTimeout = function() {
150
					wappalyzer.log('Resource timeout', 'error');
151
152
					wappalyzer.driver.sendResponse();
153
154
					phantom.exit(1);
155
				};
156
157
				page.onResourceReceived = function(response) {
158
					if ( response.url.replace(/\/$/, '') === url.replace(/\/$/, '') ) {
159
						if ( response.redirectURL ) {
160
							url = response.redirectURL;
161
162
							return;
163
						}
164
165
						if ( response.stage === 'end' && response.status === 200 && response.contentType.indexOf('text/html') !== -1 ) {
166
							response.headers.forEach(function(header) {
167
								headers[header.name.toLowerCase()] = header.value;
168
							});
169
						}
170
					}
171
				};
172
173
				page.onResourceError = function(resourceError) {
174
					wappalyzer.log(resourceError.errorString, 'error');
175
				};
176
177
				page.open(url, function(status) {
178
					var html, environmentVars = '';
179
180
					if ( status === 'success' ) {
181
						html = page.content;
182
183
						if ( html.length > 50000 ) {
184
							html = html.substring(0, 25000) + html.substring(html.length - 25000, html.length);
185
						}
186
187
						// Collect environment variables
188
						environmentVars = page.evaluate(function() {
189
							var i, environmentVars = '';
190
191
							for ( i in window ) {
192
								environmentVars += i + ' ';
193
							}
194
195
							return environmentVars;
196
						});
197
198
						wappalyzer.log({ message: 'environmentVars: ' + environmentVars });
199
200
						environmentVars = environmentVars.split(' ').slice(0, 500);
201
202
						wappalyzer.analyze(hostname, url, {
203
							html:    html,
204
							headers: headers,
205
							env:     environmentVars
206
						});
207
208
						phantom.exit(0);
209
					} else {
210
						wappalyzer.log('Failed to fetch page', 'error');
211
212
						wappalyzer.driver.sendResponse();
213
214
						phantom.exit(1);
215
					}
216
				});
217
			}
218
		};
219
220
		wappalyzer.init();
221
	} catch ( e ) {
222
		wappalyzer.log(e, 'error');
223
224
		wappalyzer.driver.sendResponse();
225
226
		phantom.exit(1);
227
	}
228
})();
229